﻿using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using BugTracker;

namespace RSDataEdit
{
    class DataEdit : IDisposable
    {
        #region private члены класса
            private DataGridView m_grid = null;
            private bool m_active = false;
            private RSObjects m_Object = RSObjects.NoObject;
            private RSShowTypes m_ShowType = RSShowTypes.Normal;
            private List<RSColumn> m_Collumns = new List<RSColumn>();
            private StringCollection m_cells = new StringCollection();
            private int m_rowCount = 0;
        #endregion

        #region Интерфейс IDisposable
            private bool disposed = false;
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
            private void Dispose(bool disposing)
            {
                if (!this.disposed)
                {
                    // Clear resources
                    m_active = false;
                    m_grid = null;
                    m_Collumns.Clear();
                    m_cells.Clear();
                    m_rowCount = 0;
                    if (disposing)
                    {
                        // Dispose managed resources.
                    };
        
                    // Note disposing has been done.
                    disposed = true;
                };
            }
            ~DataEdit()
            {
                Dispose(false);
            }
        #endregion

        public DataGridView DataGrid
        {
            get
            {
                return m_grid;
            }
            set
            {
                if (!Active)
                    m_grid = value;
            }
        }
        public RSObjects Object
        {
            get
            {
                return m_Object;
            }
            set
            {
                if (!Active)
                    m_Object = value;
            }
        }
        public bool Active
        {
            get
            {
                return m_active;
            }
            set
            {
                if (value)
                {
                    if (m_grid != null)
                    {
                        m_active = true;
                        Activate();
                    };
                } else
                    m_active = false;
            }
        }

        private void Activate()
        {
            if (!Active)
                return;
            InitTable();
            Refresh();
        }
        private void InitTable()
        {
            m_grid.VirtualMode = true;
            m_grid.AllowUserToAddRows = false;
            m_grid.CellValueNeeded += dataGridView_CellValueNeeded;
            m_grid.CellFormatting += dataGridView_CellFormatting;

        }
        public void Refresh()
        {
            if (!Active || !DBWork.Active)
                return;

            SaveColumnToReg();
            m_Collumns.Clear();
            m_cells.Clear();
            m_rowCount = 0;

            // Заполнение массива данных
            DBWDataSet DBSet = DBWork.ExecuteSQL(GetCommand());
            FillVisibleColumns(DBSet);
            DBSet.NextResult();
            FillOtherColumns(DBSet);
            GetCells(DBSet);
            DBSet.Dispose();

            RedrawTable();
            LoadColumnFromReg();
        }
        private void RedrawTable()
        {
            if (m_grid == null)
                return;

            m_grid.Rows.Clear();
            m_grid.Columns.Clear();

            m_grid.ColumnCount = GetVisibleCount();
            m_grid.RowCount = m_rowCount;
            m_grid.RowHeadersVisible = false;
            m_grid.AllowUserToResizeRows = false;

            // Наименования колонок
            int i = 0;
            foreach (DataGridViewColumn tmpCol in m_grid.Columns)
                tmpCol.Name = m_Collumns[i++].Description;
        }
        private void SaveColumnToReg()
        {
            if (m_Collumns.Count == 0)
                return;
            RegistryKey key = Registry.CurrentUser.OpenSubKey(constants.RegisterHome + "\\" + m_Object, RegistryKeyPermissionCheck.ReadWriteSubTree);
            if (key == null)
                key = Registry.CurrentUser.CreateSubKey(constants.RegisterHome + "\\" + m_Object, RegistryKeyPermissionCheck.ReadWriteSubTree);

            if (key != null)
            {
                /*if (WindowState != FormWindowState.Maximized)
                {
                    key.SetValue("WindowTop", Top, RegistryValueKind.DWord);
                    key.SetValue("WindowLeft", Left, RegistryValueKind.DWord);
                    key.SetValue("WindowHeight", Height, RegistryValueKind.DWord);
                    key.SetValue("WindowWidth", Width, RegistryValueKind.DWord);
                    key.SetValue("IsWindowMaximized", 0, RegistryValueKind.DWord);
                }
                else
                    key.SetValue("IsWindowMaximized", 1, RegistryValueKind.DWord);*/
                key.Close();
            };
        }
        private void LoadColumnFromReg()
        {

        }

        #region Заполнение массивов данных и прочее получение данных
            // Получение строки с запросом на получение данных
            private String GetCommand()
            {
                String ret;
                ret = "call OBJECT_GET_ITEMS(" + Convert.ToString((int)m_Object) + ", '";
                if ((int)m_ShowType != constants.EmptyID)
                    ret += "SHOW_TYPE=\"" + Convert.ToString((int)m_ShowType) + "\";";
                ret += "')";
                return ret;
            }
            // Заполнение колонок пришедших в первом наборе - те что будут отображаться
            private void FillVisibleColumns(DBWDataSet DBSet)
            {
                if (DBSet == null)
                    return;

                uint i = 0;
                while (DBSet.Read())
                {
                    if (DBSet.ErrorSet())
                        return;
                    RSColumn tmpCol = new RSColumn();
                    tmpCol.Name = DBSet.GetString("COL_NAME");
                    tmpCol.Description = DBSet.GetString("COL_DESCRIPTOR");
                    tmpCol.Visible = DBSet.FieldExists("VISIBLE") ? DBSet.GetBoolean("VISIBLE") : true;
                    if (tmpCol.Visible)
                        tmpCol.VisibleNumber = i++;
                    m_Collumns.Add(tmpCol);
                    // TODO тут нужно будет считывание этих колонок из реестра организовать, чтобы расставить порядок и видимость
                };
                IComparer<RSColumn> tmpComparer = new RSColumnComparerVidible();
                m_Collumns.Sort(tmpComparer);
            }
            // Заполнение колонок пришедших во втором наборе - сервисные
            private void FillOtherColumns(DBWDataSet DBSet)
            {
                for (int i = 0; i < DBSet.FieldCount; i++)
                {
                    RSColumn tmpCol = new RSColumn(DBSet.GetFieldName(i));
                    if (!m_Collumns.Contains(tmpCol))
                        m_Collumns.Add(tmpCol);
                };
            }
            // Заполнение ячеек
            private void GetCells(DBWDataSet DBSet)
            {
                while (DBSet.Read())
                {
                    foreach (RSColumn tmpCol in m_Collumns)
                        m_cells.Add(DBSet.GetAnythingAsString(tmpCol.Name));
                    m_rowCount++;
                };
            }
        #endregion

        #region Операции получения данных из наборов
            // Получение количества колонок для отображения
            private int GetVisibleCount()
            {
                int ret = 0;
                foreach (RSColumn tmpCol in m_Collumns)
                    if (tmpCol.Visible)
                        ret++;
                return ret;
            }
            private String GetValue(int row, int col)
            {
                return m_cells[(row * m_Collumns.Count) + col];
            }
        #endregion

        #region События DataGridView
            private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            e.Value = GetValue(e.RowIndex, e.ColumnIndex);
        }
            private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.RowIndex % 2 != 0)
                e.CellStyle.BackColor = System.Drawing.Color.Azure;
        }
        #endregion
    }
}